package com.wangyk.thymeleafproject.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.wangyk.rabbitmqcommon.model.console.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.util.Date;

/**
 * 使用Hystrix组件
 */
@Controller
@RequestMapping("/hystrix")
//给所有的方法设置默认熔断器
@DefaultProperties(defaultFallback = "defaultFallbackMethod")
public class HystrixController
{
    @Autowired
    private RestTemplate restTemplate;

    //1.设置熔断器的注解，抛出异常执行fallbackMethod方法
    @HystrixCommand(fallbackMethod = "fallbackMethod")
    @RequestMapping("/get_user_info")
    @ResponseBody
    public User getUserInfo()
    {
        User user =
            restTemplate.getForObject("http://" + "CONSOLE" + "/console/userpro/select_by_user_id.do?userId=3",
                User.class);
        return user;
    }

    //2.在类上面添加熔断器，对所有的方法有效
    @HystrixCommand
    @RequestMapping("/get_user_info2")
    @ResponseBody
    public User getUserInfo2()
    {
        User user =
            restTemplate.getForObject("http://" + "CONSOLE" + "/console/userpro/select_by_user_id.do?userId=3",
                User.class);
        throw new RuntimeException("发生异常了");
        //return user;
    }

    //3.服务访问时间超时，设置超时不熔断，设置熔断时间（默认为1000毫秒）
    @HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")})
    @RequestMapping("/get_user_info3")
    @ResponseBody
    public User getUserInfo3()
    {
        User user =
            restTemplate.getForObject("http://" + "CONSOLE" + "/console/userpro/select_by_user_id.do?userId=3",
                User.class);
        return user;
    }

    //4.服务熔断：如果服务发生异常，就不能再接收请求，服务就处于熔断状态。
    //故障达到一定的值，返回错误，启动熔断机制，对服务返回错误。
    //当时钟选项的时间达到时，就会进入半熔断状态。
    //如果请求正常返回，则会关闭熔断器。
    @HystrixCommand(commandProperties = {
        @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//
        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//断路器的最小时钟数
        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//设置熔断时钟10秒
        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),//断路器断路的百分比条件，断路器打开
    })
    @RequestMapping("/get_user_info4")
    @ResponseBody
    public User getUserInfo4(@RequestParam Integer number)
    {
        if (number % 2 == 0)
        {
            return new User();
        }
        User user = restTemplate.getForObject("http://" + "CONSOLE" + "/console/userpro/select_by_user_id.do?userId=3",
            User.class);
        return user;
    }

    //5.使用配置项来配置熔断器
    @HystrixCommand
    @RequestMapping("/get_user_info5")
    @ResponseBody
    public User getUserInfo5()
    {
        User user =
            restTemplate.getForObject("http://" + "CONSOLE" + "/console/userpro/select_by_user_id.do?userId=3",
                User.class);
        return user;
    }

    //6.使用配置项来配置熔断器，给特定的方法配置
    @HystrixCommand
    @RequestMapping("/get_user_info6")
    @ResponseBody
    public User getUserInfo6()
    {
        User user =
            restTemplate.getForObject("http://" + "CONSOLE" + "/console/userpro/select_by_user_id.do?userId=3",
                User.class);
        return user;
    }

    public User fallbackMethod()
    {
        System.out.println("执行了fallbackMethod()");
        User user=new User();
        user.setPassword("错误");
        user.setUserName("错误");
        user.setDate(new Date());
        user.setSex((byte)0);
        user.setUserId(11111);
        return user;
    }

    public User defaultFallbackMethod()
    {
        System.out.println("执行了defaultFallbackMethod()");
        User user=new User();
        user.setPassword("错误2");
        user.setUserName("错误2");
        user.setDate(new Date());
        user.setSex((byte)0);
        user.setUserId(11111);
        return user;
    }
}
